/***********************************************************************************
 * 文件名： mcu_delay.c
 * 作者： 刘言
 * 版本： 1
 * 说明：
 * 		利用定时器精确延时。
 * 修改记录：
 * 	2020/8/19: 初版。 刘言。
***********************************************************************************/
#include "mcu_delay.h"
#include "mcu.h"

/////////////////////// Delay的配置

#define DELAY_TIM_INIT                              // Delay 所使用的定时器初始化，如果在别处初始化了这里留空。
#define DELAY_COUNTER           SysTick->VAL        // 计数寄存器，默认是递减计数。
#define DELAY_COUNT_PERIOD      SYSTICK_VALUE       // 计数周期（重载值）,这里不是设置，只是告知延时驱动定时器的重载值。
#define DELAY_COUNT_PER_US      (F_HCLK / 1000000)   // 1us 的计数个数 （计数的频率，单位MHz. SysTick会被库函数设置为HCLK）



IN_LINE void Mcu_DelayInit()
{
    DELAY_TIM_INIT;
}

void Mcu_Delayus(u16 us)
{
    u32 oldcnt, newcnt; 
    u32 tcntvalue = 0;	/* 走过的总时间(时钟数)  */
    u32 total = us * DELAY_COUNT_PER_US;    // 需要等待的总时钟数

    oldcnt = DELAY_COUNTER; // DELAY_COUNTER 递减计数，计数周期时钟数为 DELAY_COUNT_PERIOD
    while(tcntvalue < total)
    {
        newcnt = DELAY_COUNTER;
        if(newcnt != oldcnt)
        {
            if(oldcnt > newcnt) // 说明递减计数没有重载
                tcntvalue += oldcnt - newcnt;
            else                // 发生重载
                tcntvalue += oldcnt + (DELAY_COUNT_PERIOD - newcnt);
            oldcnt = newcnt;
        }
    }
}

void Mcu_Delayms(uint32_t ms)
{
    while(ms--)
	{
		Mcu_Delayus(1000);
	}
}

/**
 * 重定义 HAL_Delay 给HAL库使用，用户一般不要使用
*/
IN_LINE void HAL_Delay(uint32_t Delay)
{
    Mcu_Delayms(Delay);
}


